package com.it.schoolhomeos.service.impl;

import com.it.schoolhomeos.dto.AttendanceBatchDTO;
import com.it.schoolhomeos.dto.AttendanceStatDTO;
import com.it.schoolhomeos.dto.StudentAttendanceDTO;
import com.it.schoolhomeos.entity.Attendance;
import com.it.schoolhomeos.entity.Attendance.AttendanceStatus;
import com.it.schoolhomeos.entity.ClassInfo;
import com.it.schoolhomeos.entity.Student;
import com.it.schoolhomeos.entity.User;
import com.it.schoolhomeos.repository.AttendanceRepository;
import com.it.schoolhomeos.repository.ClassInfoRepository;
import com.it.schoolhomeos.repository.StudentRepository;
import com.it.schoolhomeos.repository.UserRepository;
import com.it.schoolhomeos.service.AttendanceService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * AttendanceService接口的实现类
 * 
 * 实现考勤相关的业务逻辑
 */
@Service
@Transactional
public class AttendanceServiceImpl implements AttendanceService {

    private static final Logger logger = LoggerFactory.getLogger(AttendanceServiceImpl.class);

    @Autowired
    private AttendanceRepository attendanceRepository;
    
    @Autowired
    private ClassInfoRepository classInfoRepository;
    
    @Autowired
    private StudentRepository studentRepository;
    
    @Autowired
    private UserRepository userRepository;
    
    /**
     * 获取当前教师的班级
     * 
     * @return 当前教师的班级
     */
    @Override
    public ClassInfo getCurrentTeacherClass() {
        // 获取当前登录用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        
        // 查询用户信息
        User teacher = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 查询教师的班级
        List<ClassInfo> classes = classInfoRepository.findByTeacher(teacher);
        if (classes.isEmpty()) {
            throw new RuntimeException("当前教师没有关联的班级");
        }
        
        // 返回第一个班级（假设一个教师只关联一个班级）
        return classes.get(0);
    }
    
    /**
     * 获取当前教师班级的近七天考勤统计
     * 
     * @return 近七天的考勤统计列表
     */
    @Override
    public List<AttendanceStatDTO> getLastSevenDaysAttendanceStat() {
        // 获取当前教师的班级
        ClassInfo classInfo = getCurrentTeacherClass();
        
        // 计算近七天的日期范围
        LocalDate today = LocalDate.now();
        LocalDate sevenDaysAgo = today.minusDays(6);
        
        // 查询班级学生总数
        int totalStudents = studentRepository.findByClassInfo(classInfo).size();
        
        // 查询近七天的考勤记录
        List<Attendance> attendances = attendanceRepository.findByStudentClassInfoAndDateBetween(
                classInfo, sevenDaysAgo, today);
        
        // 按日期分组统计
        List<AttendanceStatDTO> stats = new ArrayList<>();
        for (int i = 0; i <= 6; i++) {
            LocalDate date = sevenDaysAgo.plusDays(i);
            AttendanceStatDTO stat = getAttendanceStatByDate(date);
            stats.add(stat);
        }
        
        return stats;
    }
    
    /**
     * 获取当前教师班级的今日考勤统计
     * 
     * @return 今日考勤统计
     */
    @Override
    public AttendanceStatDTO getTodayAttendanceStat() {
        return getAttendanceStatByDate(LocalDate.now());
    }
    
    /**
     * 获取当前教师班级指定日期的考勤统计
     * 
     * @param date 日期
     * @return 指定日期的考勤统计
     */
    @Override
    public AttendanceStatDTO getAttendanceStatByDate(LocalDate date) {
        // 获取当前教师的班级
        ClassInfo classInfo = getCurrentTeacherClass();
        
        // 查询班级学生总数
        int totalStudents = studentRepository.findByClassInfo(classInfo).size();
        
        // 查询各状态的考勤记录数量
        int presentCount = attendanceRepository.countByStudentClassInfoAndDateAndStatus(
                classInfo, date, AttendanceStatus.PRESENT);
        int absentCount = attendanceRepository.countByStudentClassInfoAndDateAndStatus(
                classInfo, date, AttendanceStatus.ABSENT);
        int leaveCount = attendanceRepository.countByStudentClassInfoAndDateAndStatus(
                classInfo, date, AttendanceStatus.LEAVE);
        
        // 创建并返回统计对象
        AttendanceStatDTO stat = AttendanceStatDTO.builder()
                .date(date)
                .presentCount(presentCount)
                .absentCount(absentCount)
                .leaveCount(leaveCount)
                .totalCount(totalStudents)
                .build();
        
        // 计算比率
        stat.calculateRates();
        
        return stat;
    }
    
    /**
     * 获取当前教师班级指定日期的学生考勤详情
     * 
     * @param date 日期
     * @return 学生考勤详情列表
     */
    @Override
    public List<StudentAttendanceDTO> getStudentAttendanceDetailsByDate(LocalDate date) {
        // 获取当前教师的班级
        ClassInfo classInfo = getCurrentTeacherClass();
        
        // 查询班级所有学生
        List<Student> students = studentRepository.findByClassInfo(classInfo);
        
        // 查询当天的考勤记录
        List<Attendance> attendances = attendanceRepository.findByStudentClassInfoAndDateList(classInfo, date);
        
        // 将考勤记录转换为Map，方便查找
        var attendanceMap = attendances.stream()
                .collect(Collectors.toMap(a -> a.getStudent().getId(), a -> a));
        
        // 构建学生考勤详情列表
        List<StudentAttendanceDTO> result = new ArrayList<>();
        for (Student student : students) {
            Attendance attendance = attendanceMap.get(student.getId());
            
            StudentAttendanceDTO dto = StudentAttendanceDTO.builder()
                    .studentId(student.getId())
                    .studentNumber(student.getStudentNumber())
                    .name(student.getName())
                    .gender(student.getGender())
                    .build();
            
            if (attendance != null) {
                dto.setStatus(attendance.getStatus());
                dto.setAttendanceId(attendance.getId());
                dto.setRemarks(attendance.getRemarks());
            }
            
            result.add(dto);
        }
        
        return result;
    }
    
    /**
     * 批量提交学生考勤
     * 
     * @param attendanceBatchDTO 批量考勤数据
     * @return 提交成功的考勤记录数量
     */
    @Override
    @Transactional
    public int submitAttendanceBatch(AttendanceBatchDTO attendanceBatchDTO) {
        // 获取当前教师的班级
        ClassInfo classInfo = getCurrentTeacherClass();
        
        // 获取考勤日期
        LocalDate date = attendanceBatchDTO.getDate();
        if (date == null) {
            date = LocalDate.now();
        }
        
        // 删除当天已有的考勤记录
        List<Attendance> existingAttendances = attendanceRepository.findByStudentClassInfoAndDateList(classInfo, date);
        if (!existingAttendances.isEmpty()) {
            attendanceRepository.deleteAll(existingAttendances);
        }
        
        // 创建新的考勤记录
        List<Attendance> newAttendances = new ArrayList<>();
        LocalDateTime now = LocalDateTime.now();
        
        for (AttendanceBatchDTO.StudentAttendanceItem item : attendanceBatchDTO.getAttendances()) {
            // 查询学生信息
            Student student = studentRepository.findById(item.getStudentId())
                    .orElseThrow(() -> new RuntimeException("学生不存在: " + item.getStudentId()));
            
            // 创建考勤记录
            Attendance attendance = new Attendance();
            attendance.setStudent(student);
            attendance.setClassInfo(classInfo);
            attendance.setDate(date);
            attendance.setStatus(item.getStatus());
            attendance.setRemarks(item.getRemarks());
            attendance.setCreateTime(now);
            attendance.setUpdateTime(now);
            
            newAttendances.add(attendance);
        }
        
        // 保存考勤记录
        List<Attendance> savedAttendances = attendanceRepository.saveAll(newAttendances);
        
        return savedAttendances.size();
    }
    
    /**
     * 家长查看学生考勤记录
     * 
     * @param studentId 学生ID
     * @param startDate 开始日期，可为null
     * @param endDate 结束日期，可为null
     * @return 学生考勤详情列表
     */
    @Override
    public List<StudentAttendanceDTO> getStudentAttendanceByParent(Long studentId, LocalDate startDate, LocalDate endDate) {
        // 获取当前登录用户
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        String username = authentication.getName();
        
        // 查询用户信息
        User parent = userRepository.findByUsername(username)
                .orElseThrow(() -> new RuntimeException("用户不存在"));
        
        // 验证该学生是否属于当前家长
        Student student = studentRepository.findByIdAndParentId(studentId, parent.getId())
                .orElseThrow(() -> new RuntimeException("无权查看该学生的考勤记录"));
        
        // 查询考勤记录
        List<Attendance> attendances;
        if (startDate != null && endDate != null) {
            attendances = attendanceRepository.findByStudentIdAndDateBetween(studentId, startDate, endDate);
        } else if (startDate != null) {
            attendances = attendanceRepository.findByStudentIdAndDateGreaterThanEqual(studentId, startDate);
        } else if (endDate != null) {
            attendances = attendanceRepository.findByStudentIdAndDateLessThanEqual(studentId, endDate);
        } else {
            // 默认查询最近30天的记录
            LocalDate thirtyDaysAgo = LocalDate.now().minusDays(30);
            attendances = attendanceRepository.findByStudentIdAndDateGreaterThanEqual(studentId, thirtyDaysAgo);
        }
        
        // 转换为DTO
        return attendances.stream()
                .map(a -> StudentAttendanceDTO.builder()
                        .studentId(student.getId())
                        .studentNumber(student.getStudentNumber())
                        .name(student.getName())
                        .gender(student.getGender())
                        .status(a.getStatus())
                        .attendanceId(a.getId())
                        .remarks(a.getRemarks())
                        .build())
                .collect(Collectors.toList());
    }
} 